#include"include/controlwidget.h"
#include"include/playlistwidget.h"
#include"include/trackplayer.h"
#include"include/lyricsetting.h"
#include"include/lyricpanel.h"
#include"include/lyric.h"
#include"include/lyrictool.h"
#include"include/lyricsearchwidget.h"
#include"ui_controlwidget.h"
ControlWidget::ControlWidget(QWidget *parent):QWidget(parent),ui(new Ui::ControlWidget)
{
    //    creatWidgets();
    ui->setupUi(this);
    initWgt();
    creatActions();
    creatConnections();
}

void ControlWidget::initWgt()
{
    setFixedSize(300,150);
    setWindowTitle(QObject::tr("Minip"));
    setMouseTracking(true);
    player=new TrackPlayer(this);
    trayIcon=new QSystemTrayIcon(this);
    trayIcon->setIcon(QIcon(":/data/icons/music.png"));
    ui->timeLCD->display("00:00");
    ui->seekSlider->setMediaObject(player->mediaObject);
    ui->volumeSlider->setAudioOutput(player->audioOutput);

    playListWgt=new PlayListWidget(this);
    playListWgt->setPlayer(player);
    playListWgt->setPlayMode(ORDINALPLAY);
    QPoint p=pos();
    QPoint gPos=mapToGlobal(p);
    int x1=gPos.x();
    int y1=gPos.y()+frameGeometry().height();
    playListWgt->move(x1,y1);
    playListWgt->show();

    lyricSettings=0;
    lyricPanel=0;
    lrcSearchWgt=0;
    lrc=0;
    haveLyricPanel=false;
    lyricReady=false;
    haveNext=false;
}

void ControlWidget::creatActions()
{
    showMainWindowAct=new QAction(QObject::tr("&Show Main Window"),this);
    prevTrackAct=new QAction(QObject::tr("P&revious Track"),this);
    prevTrackAct->setShortcut(QKeySequence(Qt::Key_MediaPrevious));
    prevTrackAct->setShortcutContext(Qt::ApplicationShortcut);
    nextTrackAct=new QAction(QObject::tr("&Next Track"),this);
    nextTrackAct->setShortcut(QKeySequence(Qt::Key_MediaNext));
    nextTrackAct->setShortcutContext(Qt::ApplicationShortcut);
    playOrPauseAct=new QAction(QObject::tr("&Play"),this);
    playOrPauseAct->setShortcut(QKeySequence(Qt::Key_MediaPlay));
    playOrPauseAct->setShortcutContext(Qt::ApplicationShortcut);
    lockDesktopLyricAct=new QAction(QObject::tr("Lock Desktop Lyrics"),this);
    lockDesktopLyricAct->setEnabled(false);
    lockDesktopLyricAct->setCheckable(true);
    lyricSettingAct=new QAction(QObject::tr("Lyrics &Settings"),this);
    quitAct=new QAction(QObject::tr("&Quit"),this);
    trayMenu=new QMenu(this);
    trayMenu->addAction(showMainWindowAct);
    trayMenu->addAction(prevTrackAct);
    trayMenu->addAction(playOrPauseAct);
    trayMenu->addAction(nextTrackAct);
    trayMenu->addAction(lockDesktopLyricAct);
    trayMenu->addAction(lyricSettingAct);
    trayMenu->addAction(quitAct);
    trayIcon->setContextMenu(trayMenu);
    trayIcon->show();

    desktopLyricAct=new QAction(QObject::tr("Desktop Lyrics"),this);
    desktopLyricAct->setShortcut(QKeySequence(Qt::ALT+Qt::Key_D));
    desktopLyricAct->setShortcutContext(Qt::ApplicationShortcut);
    desktopLyricAct->setCheckable(true);

    searchLyricAct=new QAction(QObject::tr("Search Lyrics"),this);
    lyricMenu=new QMenu(this);
    lyricMenu->addAction(desktopLyricAct);
    lyricMenu->addAction(searchLyricAct);
    lyricMenu->addAction(lyricSettingAct);
    ui->lyricBtn->setMenu(lyricMenu);
    ui->lyricBtn->setPopupMode(QToolButton::InstantPopup);

    ordinalPlayAct=new QAction(QObject::tr("Ordinal Play"),this);
    listRepeatAct=new QAction(QObject::tr("Playlist Repeat"),this);
    trackRepeatAct=new QAction(QObject::tr("Single Repeat"),this);
    randomPlayAct=new QAction(QObject::tr("Random Play"),this);
    modeActList<<ordinalPlayAct<<listRepeatAct<<trackRepeatAct<<randomPlayAct;
    playModeMenu=new QMenu(this);
    for(int i=0;i<modeActList.size();++i)
    {
        modeActList[i]->setData(i);
        modeActList[i]->setCheckable(true);
        playModeMenu->addAction(modeActList[i]);
    }
    modeActList[0]->setChecked(true);
    ui->modeBtn->setMenu(playModeMenu);
    ui->modeBtn->setPopupMode(QToolButton::InstantPopup);
}

void ControlWidget::creatConnections()
{
    connect(showMainWindowAct,SIGNAL(triggered()),this,SLOT(showAll()));
    connect(trayIcon,SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
            this,SLOT(onTrayIconActived(QSystemTrayIcon::ActivationReason)));
    connect(quitAct,SIGNAL(triggered()),this,SLOT(quit()));
    connect(lyricSettingAct,SIGNAL(triggered()),this,SLOT(onLyricSetTriggered()));
    connect(ui->nextBtn,SIGNAL(clicked()),playListWgt,SLOT(playNextTrack()));
    connect(ui->prevBtn,SIGNAL(clicked()),playListWgt,SLOT(playPrevTrack()));
    connect(ui->playBtn,SIGNAL(toggled(bool)),playListWgt,SLOT(playOrPause(bool)));
    connect(ui->playBtn,SIGNAL(toggled(bool)),this,SLOT(onPlayBtnToggled(bool)));
    connect(ui->stopBtn,SIGNAL(clicked()),playListWgt,SLOT(stop()));
    connect(player->mediaObject,SIGNAL(stateChanged(Phonon::State,Phonon::State)),
            this,SLOT(onStateChanged(Phonon::State,Phonon::State)));
    connect(playListWgt,SIGNAL(closeRequest()),this,SLOT(onListCloseRequested()));
    connect(ui->listBtn,SIGNAL(toggled(bool)),this,SLOT(onShowListToggled(bool)));
    connect(player->mediaObject,SIGNAL(tick(qint64)),this,SLOT(onTick(qint64)));
    connect(desktopLyricAct,SIGNAL(toggled(bool)),this,SLOT(onDesktopLyricToggled(bool)));
    connect(player->mediaObject,SIGNAL(aboutToFinish()),this,SLOT(onAboutToFinish()));
    connect(nextTrackAct,SIGNAL(triggered()),playListWgt,SLOT(playNextTrack()));
    connect(prevTrackAct,SIGNAL(triggered()),playListWgt,SLOT(playPrevTrack()));
    connect(searchLyricAct,SIGNAL(triggered()),this,SLOT(onSearchLyricTriggered()));
    for(int i=0;i<modeActList.size();++i)
    {
        connect(modeActList[i],SIGNAL(triggered()),this,SLOT(onPlayModeChanged()));
    }
}

void ControlWidget::setPlayer(Phonon::AudioOutput *output, Phonon::MediaObject *object)
{
    ui->volumeSlider->setAudioOutput(output);
    ui->seekSlider->setMediaObject(object);
}

void ControlWidget::onShowListToggled(bool b)
{
    playListWgt->setVisible(b);
}

void ControlWidget::onShowLyricWgtToggled(bool b)
{
    emit showLyricWgt(b);
}


void ControlWidget::onPlayBtnToggled(bool b)
{
        ui->playBtn->setToolTip(b?(QObject::tr("Pause")):(QObject::tr("Play")));
}
void ControlWidget::onStateChanged(Phonon::State newState, Phonon::State oldState)
{
    if(newState==Phonon::PlayingState)
    {
        bool b=ui->playBtn->isChecked();
        haveNext=false;
        QString tkName=player->currentTackName();
        QStringList infoList=LyricTool::trackInfo(tkName);
        QString infoFromID3(infoList.join(""));
        if(infoList.size()>1&&(!infoFromID3.isEmpty()))
        {
            QString info(infoList[0]);
            info.append("\n").append(infoList[1]);
            ui->infoLbl->setText(info);
        }
        else
        {
            QFileInfo f(tkName);
            QString tmpStr(f.fileName());
            QString name=tmpStr.left(tmpStr.lastIndexOf("."));      //get the track name without suffix
            ui->infoLbl->setText(name);
        }
        if(!b)
            ui->playBtn->setChecked(true);
        if(haveLyricPanel)
        {
            if(lrc)
            {
                lyricReady=false;
                delete lrc;
                lrc=0;
            }
            QString fileName=LyricTool::lyricFileName(player->currentTackName());
            if(QFile::exists(fileName))
            {
                lrc=new Lyrics(fileName);
                lyricReady=true;
            }
            else
            {
                lyricReady=false;
                lrcSearchWgt=new LyricSearchWidget(player->currentTackName());
                connect(lrcSearchWgt,SIGNAL(downFinished(QString)),this,SLOT(onDownFinished(QString)));
            }
        }
    }
    else
        ui->playBtn->setChecked(false);
    if(newState==Phonon::StoppedState)
    {
        ui->timeLCD->display("00:00");
        ui->infoLbl->setText(QObject::tr("No Track Playing..."));
        if(haveLyricPanel)
        {
            if(lyricReady)
                delete lrc;
            lrc=0;
            lyricReady=false;
            lyricPanel->setText(QString());
            lyricPanel->update();
        }
        if(haveNext)                        //auto playing next track
            playListWgt->playNextTrack();
    }

}

void ControlWidget::onLyricSetTriggered()
{
    lyricSettings=new LyricSetting();
    lyricSettings->show();
    connect(lyricSettings,SIGNAL(closeRequest()),this,SLOT(onLyricSettingClosed()));
}

void ControlWidget::onLyricSettingClosed()
{
    disconnect(lyricSettings,0,0,0);
    delete lyricSettings;
    lyricSettings=0;
}

void ControlWidget::onListCloseRequested()
{
    ui->listBtn->setChecked(false);
    playListWgt->setVisible(false);
}

void ControlWidget::onTick(qint64 t)
{
    qint64 s=t/1000;
    QTime tt(s/3600,(s%3600)/60,s%60);
    ui->timeLCD->display(tt.toString("mm:ss"));
    if(haveLyricPanel&&lyricPanel&&lyricReady)
    {
        lyricPanel->setText(lrc->getLyrics(t));
        lyricPanel->update();          //update desktop lyric
    }
}

void ControlWidget::onDesktopLyricToggled(bool b)
{
    haveLyricPanel=b;
    if(b)
    {
        lyricPanel=new LyricPanel();
        if(player->mediaObject->state()==Phonon::PlayingState) //if toggle the desktop lyric when playing
        {
            lyricReady=false;
            QString fileName=LyricTool::lyricFileName(player->currentTackName());
            qDebug()<<fileName<<"\n";
            if(QFile::exists(fileName))
            {
                lrc=new Lyrics(fileName);
                lyricReady=true;
            }
            else
            {
                lyricReady=false;
                lrcSearchWgt=new LyricSearchWidget(player->currentTackName());
                connect(lrcSearchWgt,SIGNAL(downFinished(QString)),this,SLOT(onDownFinished(QString)));
            }
        }
        lockDesktopLyricAct->setChecked(lyricPanel->isLocked());
        connect(lyricPanel,SIGNAL(needed(bool)),desktopLyricAct,SLOT(setChecked(bool)));
        connect(lyricPanel,SIGNAL(needed(bool)),lockDesktopLyricAct,SLOT(setEnabled(bool)));
        connect(lockDesktopLyricAct,SIGNAL(toggled(bool)),lyricPanel,SLOT(setLocked(bool)));
        lyricPanel->show();
        lockDesktopLyricAct->setEnabled(true);
    }
    else
    {
        if(lyricPanel)
        {
            disconnect(lyricPanel,0,0,0);
            disconnect(lockDesktopLyricAct,0,0,0);
            lockDesktopLyricAct->setChecked(false);
            lockDesktopLyricAct->setEnabled(false);
            delete lyricPanel;
            lyricReady=false;
            lyricPanel=0;
            delete lrc;
            lrc=0;
        }
    }
}

void ControlWidget::closeEvent(QCloseEvent *ce)
{
    playListWgt->setVisible(false);
    this->setVisible(false);
    ce->setAccepted(false);
}

void ControlWidget::quit()
{
    QApplication::quit();
}

void ControlWidget::showAll()
{
    if(this->isVisible())
    {
        ui->listBtn->setChecked(false);
        this->setVisible(false);
    }
    else
    {
        ui->listBtn->setChecked(true);
        this->setVisible(true);
    }
}

void ControlWidget::onDownFinished(QString tkName)
{
    if(tkName==player->currentTackName())
    {
        if(haveLyricPanel)
        {
            lyricReady=false;
            if(lrc)
                delete lrc;
            lrc=new Lyrics(LyricTool::lyricFileName(tkName));
            lyricReady=true;
        }
    }
}

void ControlWidget::onAboutToFinish()
{
    haveNext=true;
}

void ControlWidget::onSearchLyricTriggered()
{
    LyricSearchWidget *lrcSearch=new LyricSearchWidget(player->currentTackName());
    lrcSearch->show();
    connect(lrcSearch,SIGNAL(downFinished(QString)),this,SLOT(onDownFinished(QString)));
}

void ControlWidget::onTrayIconActived(QSystemTrayIcon::ActivationReason reason)
{
    if(reason==QSystemTrayIcon::Trigger)
        showAll();
}

void ControlWidget::onPlayModeChanged()
{
    QAction *act=qobject_cast<QAction*>(sender());
    int idx=act->data().toInt();
    for(int i=0;i<modeActList.size();++i)
    {
        if(idx!=i)
             modeActList[i]->setChecked(false);
        else
            modeActList[i]->setChecked(true);
    }
    playListWgt->setPlayMode(PlayMode(idx));
}
